#!/usr/local/bin/perl
package VER;
use strict; use warnings;

use Glib qw/TRUE FALSE/;

#
my @pixs;
my @alps;
#
my $win;
my $dare;
my $gbg;
my $sid;
my $tid;
my $kf;
my $ka;
my ($w,$h);
my ($px,$py);
my $time;
#
my $FONT;
my $PROG;
my $VER;
my $COPY;

sub delete
{
    $win->hide;
    Glib::Source->remove($tid) if defined $tid;
    Glib::Source->remove($sid) if defined $sid;
    undef $tid;
    undef $sid;
    undef $win;
    undef $dare;
    undef $gbg;
    undef $kf;
    undef $ka;
    undef $w;
    undef $h;
    undef $px;
    undef $py;
    undef $time;
    undef @pixs;
    undef @alps;
    undef $FONT;
    undef $PROG;
    undef $VER;
    undef $COPY;
    return FALSE;
}

sub show_about
{
    my @LOGO;
    my ($X,$Y,$WX,$WY);
    ($X,$Y,$WX,$WY,$FONT,$PROG,$VER,$COPY,@LOGO)=@_;
    @alps=(
	0.00275828221038,
	0.00411487352451,
	0.00613866995153,
	0.00915781944437,
	0.01366186122365,
	0.02038110198918,
	0.03040503131261,
	0.04535897664471,
	0.06766764161831,
	0.10094825899733,
	0.15059710595610,
	0.22466448205861,
	0.33516002301782,
	0.5);
    $win=Gtk2::Window->new();
    $win->signal_connect(delete_event => sub{$win->destroy;});
    $win->signal_connect(destroy => \&delete);
    $win->signal_connect(key_press_event => \&delete);
    $win->set_border_width(0); # <<<
    $w=400;
    $h=$w/((1+sqrt(5))/2);
    ($px,$py)=(20,($h-128)/2);
    $win->set_default_size($w,$h);
    $win->set_size_request($w,$h);
    $win->set_decorated(FALSE);
    $win->set_title("About $PROG");
    $win->set_resizable(FALSE);
    $dare=Gtk2::DrawingArea->new;
    $dare->signal_connect(expose_event=>\&expose);
    $win->add($dare);
    $dare->modify_bg("normal",Gtk2::Gdk::Color->parse("black"));
    foreach(@LOGO){
	push @pixs, Gtk2::Gdk::Pixbuf->new_from_file($_);
    }
    $kf=-1;
    $ka=-4;
    $time=0;
    $win->set_modal(TRUE);
    $win->move($X+($WX-$w)/2,$Y+($WY-$h)/2);
    $win->show_all;
    &slide;
    &timer;
}

sub timer
{
    $tid=Glib::Timeout->add(100,sub{$time++;
				    $dare->queue_draw;
				    return TRUE});
}

sub slide
{
    $sid=Glib::Timeout->add(200,sub
			    {
				$ka++;
				$dare->queue_draw_area($px,$py,128,128); #<<<<
				return TRUE;
			    });
}

sub expose
{
    require "Cairo.pm";
    my ($x1,$y1,$x2,$y2)=$_[1]->area->values;
    $x2+=$x1; $y2+=$y1;
    my $cr=Gtk2::Gdk::Cairo::Context->create($dare->window);
    unless(defined($gbg)){
	$gbg=Cairo::LinearGradient->create(0,0,0,$h-1);
	$gbg->add_color_stop_rgb(0,   0,   0,   0);
	$gbg->add_color_stop_rgb(0.2, 0.0, 0.0, 0.4);
	$gbg->add_color_stop_rgb(0.5, 0.7, 0.8, 0.9);
	$gbg->add_color_stop_rgb(0.8, 0.0, 0.0, 0.4);
	$gbg->add_color_stop_rgb(1,   0,   0,   0);
    }
    $cr->set_source($gbg);
    $cr->fill;
    $cr->paint;

    my ($a,$b);
    my $kg=(($kf==$#pixs)?0:$kf+1);
    if($ka<=$#alps){
	$b=$ka>=0?$alps[$ka]:0;
	$a=1-$b;
    }elsif((my $j=2*$#alps-$ka)>=0){
	$a=$alps[$j];
	$b=1-$a;
    }else{
	# the end of transition
	$b=1;
	$a=0;
	$ka=-1;
	Glib::Source->remove($sid);
	undef $sid;
	Glib::Timeout->add_seconds(5,sub{&slide;return FALSE;});
    }
    if($kf>=0){
	Gtk2::Gdk::Cairo::Context::set_source_pixbuf($cr,$pixs[$kf],$px,$py);
	$cr->paint_with_alpha($a);
    }
    Gtk2::Gdk::Cairo::Context::set_source_pixbuf($cr,$pixs[$kg],$px,$py);
    $cr->paint_with_alpha($b);
    $kf=(($kf==$#pixs)?0:$kf+1) if $a==0;

    my $ty=$py-8;
    my $tx=$px+128+20;

    return if ($x2<$tx && !defined$tid);

    my $pt=sub{
	my ($x,$y,$s,$b,$i,$f,$t,@c)=@_;
	$cr->select_font_face($FONT,($i?"italic":"normal"),($b?"bold":"normal"));
	$cr->set_font_size($s);
	my ($tw,$th,$bx,$by)=($cr->text_extents($t)->{"width"},
			      $cr->text_extents($t)->{"height"},
			      $cr->text_extents($t)->{"x_bearing"},
			      $cr->text_extents($t)->{"y_bearing"});
    	$cr->move_to($x-$bx,$y-$by); #<<<
	$cr->text_path($t);
	if($#c==0){
	    $cr->set_source($c[0]);
	}else{
	    $cr->set_source_rgba(@c);
	}
	if($f){
	    $cr->set_line_width($f);
	    $cr->stroke;
	}else{
	    $cr->fill;#_preserve;
	}
    };

    my $as0=0.26;
    my $as=$as0;
    my $at=1;
    my $av=1;
    my $ac=0.9;

    my @sc=(0,   0,   0);
    my @tc=(0.1, 0.8, 0.9);
    my @uc=(0.9, 0.1, 0.8);
    my @vc=(0,   0,   0.4);
    my @cc=(0.8, 0.9, 1.0);

    my $d=(1.3*$time-$ty);
    my $y=$ty+$d;

    $y=$d<0?$ty+$d:$ty;

    my $gt=Cairo::LinearGradient->create(0,0,0,$ty+26);
    if($d<0){
	$at=(1+$d/($ty));
	$as=$as0*$at;
    }
    $gt->add_color_stop_rgba(0.82,@tc,$at);
    $gt->add_color_stop_rgba(1.00,@uc,$at);

    $pt->($tx+2, $y+2,   32,1,0,4,$PROG,@sc,$as);
    $pt->($tx,   $y,     32,1,0,0,$PROG,$gt);

    my $t1=35;
    my $d1=40;
    return if $time<$t1;
    if($time>=$t1&&$time<=$t1+$d1){
	$av=($time-$t1)/$d1;
	$as=$as0*$av;
    }
    $ty+=50;
    $pt->($tx+1, $ty+1, 18,1,1,2,$VER,@sc,$as);
    $pt->($tx,   $ty,   18,1,1,0,$VER,@vc,$av);

    my $t2=45;
    my $d2=40;
    return if $time<$t2;
    if($time>=$t2&&$time<=$t2+$d2){
	$ac=$ac*($time-$t2)/$d2;
    }else{
	Glib::Source->remove($tid) if defined $tid;
	undef $tid;
    }
    $ty+=80;
    $pt->($tx+1, $ty+1, 12,0,0,1,$COPY,@sc,$as);
    $pt->($tx,   $ty,   12,0,0,0,$COPY,@cc,$ac);

    return TRUE;
}

1;
